package Objects;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Parser {
	private Config myConfig;
	private Neighbors myNeighbors;
	private String myRouterID;
	public static String mapFileName;

	public Parser() {
		myConfig = new Config();
		myNeighbors = new Neighbors();
	}

	public Config getMyConfig() {
		return myConfig;
	}

	public Neighbors getMyNeighbors() {
		return myNeighbors;
	}

	public String getMyRouterID() {
		return myRouterID;
	}


	public void setMyConfig(Config myConfig) {
		this.myConfig = myConfig;
	}

	public void setMyNeighbors(Neighbors myNeighbors) {
		this.myNeighbors = myNeighbors;
	}

	public void setMyRouterID(String myRouterID) {
		this.myRouterID = myRouterID;
	}


	public void readConfigFile(String fileName) {
		Scanner fin = null;
		try {
			fin = new Scanner(new FileReader(fileName));
		} catch (IOException e) {
			e.printStackTrace();
		}
		List<String> allLines = new ArrayList<String>();
		while (fin.hasNextLine()) {
			allLines.add(fin.nextLine());
		}
		for (int i = 0; i < allLines.size(); i++) {
			// match pattern between ( and ) to get the individual configs
			Pattern pattern = Pattern.compile("\\((.*?)\\)", Pattern.DOTALL);
			Matcher matcher = pattern.matcher(allLines.get(i));
			ArrayList<String> configs = new ArrayList<String>();
			// System.out.println("My router ID: "+myRouterID);
			int myConfigLine = 1;

			matcher.find();
			String config = matcher.group(1);
			String[] parts = config.split(",");
			// System.out.println(parts[0]);
			if (!parts[0].trim().equals(myRouterID)) {
				myConfigLine = 0;
			}

			// System.out.println("This is my config line: "+myConfigLine);

			if (myConfigLine == 1) {
				configs.add(config);
				while (matcher.find()) {
					config = matcher.group(1);
					configs.add(config);
				}
				// System.out.println("configs.get(0): "+configs.get(0));
				String[] myConfigString = configs.get(0).split(",");
				// System.out.println(Arrays.toString(myConfigString));
				myConfig.setRouterID(myConfigString[0].trim());
				myConfig.setUDPPort(Integer.parseInt(myConfigString[1].trim()));
				myConfig.setIG(myConfigString[2].trim().charAt(0));

				for (int j = 1; j < configs.size(); j++) {
					String[] configString = configs.get(j).split(",");
					Config neighbor = new Config();
					neighbor.setRouterID(configString[0].trim());
					neighbor.setUDPPort(Integer.parseInt(configString[1].trim()));
					neighbor.setIG(configString[2].trim().charAt(0));
					myNeighbors.addNeighbor(neighbor);
				}
			}
			// System.out.println(allLines.get(i));
		}
		// System.out.println("My Config: " + myConfig);
		// System.out.println("My Neighbors: " + myNeighbors);
	}

	public static String getRouterID(String ip) {
		String routerID = "";
		Scanner fin = null;
		try{
			fin = new Scanner(new FileReader(mapFileName));
		}catch(IOException e){
			e.printStackTrace();
		}
		List<String> allLines = new ArrayList<String>();
		while(fin.hasNextLine()){
			allLines.add(fin.nextLine());
		}
		for(int i = 0; i < allLines.size(); i++){
			String tempRouterID = allLines.get(i).split("=")[0].trim();
			String tempIP = allLines.get(i).split("=")[1].split(":")[0].trim();
			if(tempIP.equals(ip)){
				routerID = tempRouterID;
				break;
			}
		}
		fin.close();
		return routerID;
	}

	public void readMapFile() {
		Scanner fin = null;
		try {
			fin = new Scanner(new FileReader(mapFileName));
		} catch (IOException e) {
			e.printStackTrace();
		}
		List<String> allLines = new ArrayList<String>();
		while (fin.hasNextLine()) {
			allLines.add(fin.nextLine());
		}
		ArrayList<RouterMapping> myMappingFile = new ArrayList<RouterMapping>();
		for (int i = 0; i < allLines.size(); i++) {
			String routerID = allLines.get(i).split("=")[0];
			String ip = allLines.get(i).split("=")[1].split(":")[0];
			int abstractPort = Integer.parseInt(allLines.get(i).split("=")[1].split(":")[1]);
			int actualPort = Integer.parseInt(allLines.get(i).split("=")[2]);
			myMappingFile.add(new RouterMapping(routerID, ip, abstractPort, actualPort));
		}

		for (int i = 0; i < myNeighbors.getMyNeighbors().size(); i++) {
			for (int j = 0; j < myMappingFile.size(); j++) {
				if (myNeighbors.getMyNeighbors().get(i).getRouterID()
						.equals(myMappingFile.get(j).getNodeID())) {
					myNeighbors.getMyNeighbors().get(i).setIP(myMappingFile.get(j).getIP());
				}
			}
		}
	}

	public void writeFile() {
		try {
			File f = new File(mapFileName);
			if (!f.exists())
				f.createNewFile();
			Scanner fin = new Scanner(new FileReader(mapFileName));
			boolean myLineExists = false;
			while (fin.hasNextLine()) {
				String line = fin.nextLine();
				if (line.split("=")[0].equals(myRouterID)) {
					myLineExists = true;
					break;
				}
			}
			if (!myLineExists) {
				FileWriter fw = new FileWriter(mapFileName, true);
				fw.append(myRouterID + "=" + myConfig.getIP() + ":" + myConfig.getUDPPort() + "=20000\n");
				fw.close();
			}
			fin.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
